﻿using Data.Contexto;
using Domain.Entidades;
using Domain.Interfaces.Repositorios;
using Domain.Interfaces.Servicos;
using MoreLinq;
using Services;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Transactions;
using Services;
namespace Data.Repositorios
{
    public class DocumentosRepository : RepositoryBase<documento> , IDocumentosRepository
    {
        protected credigeralContext Dbseg = new credigeralContext();

  
        public List<VW_documentos> Listar(DateTime? dt1, DateTime? dt2, string tipo, string origem, VW_usuarios user,string desc,int tip)
        {
            try
            {
                List<VW_documentos> documentos;


                if (dt1 == null && dt2 == null && origem == "-1" && desc == "" && user != null)
                {

                    return new List<VW_documentos>() ;
                }


                if (user != null)

                {
                    documentos = Db.VW_documentos.Where(x => x.usu_codigo == user.usu_codigo).ToList();
                }
                else
                {
                    documentos = Db.VW_documentos.DistinctBy(x => x.doc_codigo).ToList();

                }

             




                    if (desc != "")
                {
                    documentos = documentos.Where(x => Generica.removerAcentos_minuscula(x.doc_desc).Contains(Generica.removerAcentos_minuscula(desc))).ToList();
                }

                if (dt1 != null)
                {
                    documentos = documentos.Where(x => x.doc_data_inclusao >= dt1).ToList();
                }

                if (dt2 != null)
                {
                    documentos = documentos.Where(x => x.doc_data_inclusao <= dt2).ToList();
                }

                if (origem != "-1")
                {
                    int ori = int.Parse(origem);
                    documentos = documentos.Where(x => x.ori_codigo == ori).ToList();
                    if (tipo != "-1")
                    {
                        int ti = int.Parse(tipo);
                        documentos = documentos.Where(x => x.doc_tipo == ti).ToList();
                    }
                }
                else
                {
                    documentos = documentos.Where(x => x.tip_codigo == tip).ToList();

                }

               return documentos.OrderByDescending(x => x.doc_data_inclusao).ThenByDescending(x => x.doc_codigo).ToList();

              
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<tipos_documentos> busca_tipos(int origem)
        {
            try
            {
                return Db.tipos_documentos.Where(x => x.ori_codigo == origem).OrderBy(x => x.tip_descricao).ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<origem_documentos> busca_origens(int tipo)
        {
            try
            {
                return Db.origem_documentos.Where(x => x.tip_codigo == tipo).OrderBy(x => x.ori_descricao).ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string Gettipos(int tipo)
        {
            try
            {
                var listtipos = from t in Db.tipos_documentos.OrderBy(x => x.tip_descricao) where t.ori_codigo == tipo select new { id = t.tip_codigo, desc = t.tip_descricao };
                var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                string sJSON = oSerializer.Serialize(listtipos.ToList());
                return sJSON;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<VW_setor> busca_setores()
        {
            try
            {
                return Dbseg.VW_setor.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Inserir(documento documento , VW_usuarios user)
        {
            FtpWebRequest objFTP = null;
            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    if (documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 4, 1) == ".")
                    {
                        documento.doc_desc = documento.arquivo.FileName.Substring(0, documento.arquivo.FileName.Length - 4);
                        documento.doc_extensao = documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 4, 4);
                    }
                    else
                    {
                        documento.doc_desc = documento.arquivo.FileName.Substring(0, documento.arquivo.FileName.Length - 5);
                        documento.doc_extensao = documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 5, 5);
                    }

                    List<usuario_documento> lista = new List<usuario_documento>();
                    string[] vetor = documento.jsusuarios.Split(',');

                    foreach (string u in vetor)
                    {
                        if (u != "0")
                        {
                            usuario_documento usu = new usuario_documento();
                            usu.usu_codigo = int.Parse(u);

                            lista.Add(usu);
                        }
                    }

                    documento.usuario_documento = lista;
                    documento.doc_data_inclusao = DateTime.Now;
                    documento.doc_hora_inclusao = DateTime.Now.ToString("t");

                    Db.documentos.Add(documento);
                    Db.SaveChanges();

                    
                    objFTP = Generica.FTPDetail(documento.doc_codigo.ToString() + documento.doc_extensao.ToString());
                    objFTP.Method = WebRequestMethods.Ftp.UploadFile;

                    int contentLen;
                    using (Stream fs = documento.arquivo.InputStream)
                    {
                        byte[] buff = new byte[fs.Length];
                        using (Stream strm = objFTP.GetRequestStream())
                        {
                            contentLen = fs.Read(buff, 0, buff.Length);

                            while (contentLen != 0)
                            {
                                strm.Write(buff, 0, buff.Length);
                                contentLen = fs.Read(buff, 0, buff.Length);
                            }

                        }
                    }

                    log logs = new log();
                    logs.log_modulo = 3;
                    logs.log_tipo = 1020;
                    logs.log_descricao = "Documento código: " + documento.doc_codigo;
                    logs.log_usuario = user.usu_codigo;
                    logs.log_data = DateTime.Now;
                    logs.log_horario = DateTime.Now.ToString("T");

                    Dbseg.log.Add(logs);
                    Dbseg.SaveChanges();

                    scope.Complete();
                }

              
            }
            catch (Exception ex)

            {
                objFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                objFTP.GetResponse();
                throw ex;
            }
        }

        public void Editar(documento documento, VW_usuarios user)
        {
            try
            {
                FtpWebRequest objFTP = null;

                using (TransactionScope scope = new TransactionScope())
                {

                    if (documento.arquivo != null)
                    {
                        objFTP = Generica.FTPDetail(documento.doc_codigo.ToString() + documento.doc_extensao.ToString());
                        objFTP.Method = WebRequestMethods.Ftp.DeleteFile;

                        try
                        {
                            objFTP.GetResponse();
                        }
                        catch (Exception)
                        {


                        }
                        finally
                        {

                            objFTP = null;
                        }


                        if (documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 4, 1) == ".")
                        {
                            documento.doc_desc = documento.arquivo.FileName.Substring(0,
                                documento.arquivo.FileName.Length - 4);
                            documento.doc_extensao =
                                documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 4, 4);
                        }
                        else
                        {
                            documento.doc_desc = documento.arquivo.FileName.Substring(0,
                                documento.arquivo.FileName.Length - 5);
                            documento.doc_extensao =
                                documento.arquivo.FileName.Substring(documento.arquivo.FileName.Length - 5, 5);
                        }


                    }


                    //Db.usuario_documento.RemoveRange(Db.usuario_documento.Where(x => x.doc_codigo == documento.doc_codigo));


                    //List<usuario_documento> lista = new List<usuario_documento>();

                    //string[] vetor = documento.jsusuarios.Split(',');

                    //foreach (string u in vetor)
                    //{
                    //    if (u != "0")
                    //    {
                    //        usuario_documento usu = new usuario_documento();
                    //        usu.usu_codigo = int.Parse(u);
                    //        usu.doc_codigo = documento.doc_codigo;
                    //      documento.usuario_documento.Add(usu);
                    //    }
                    //}

                  

                    //Db.usuario_documento.AddRange(documento.usuario_documento);

                    documento.usuario_documento = null;


                    documento.doc_data_inclusao = DateTime.Now;
                    documento.doc_hora_inclusao = DateTime.Now.ToString("t");

                    Db.Entry(documento).State = EntityState.Modified;
                    Db.SaveChanges();



                    log logs = new log();
                    logs.log_modulo = 3;
                    logs.log_tipo = 1022;
                    logs.log_descricao = "Documento código: " + documento.doc_codigo;
                    logs.log_usuario = user.usu_codigo;
                    logs.log_data = DateTime.Now;
                    logs.log_horario = DateTime.Now.ToString("T");

                    Dbseg.log.Add(logs);
                    Dbseg.SaveChanges();

                    scope.Complete();



                    if (documento.arquivo != null)
                    {
                        objFTP = Generica.FTPDetail(documento.doc_codigo.ToString() + documento.doc_extensao.ToString());
                        objFTP.Method = WebRequestMethods.Ftp.UploadFile;
                        int contentLen;
                        using (Stream fs = documento.arquivo.InputStream)
                        {
                            byte[] buff = new byte[fs.Length];
                            using (Stream strm = objFTP.GetRequestStream())
                            {
                                contentLen = fs.Read(buff, 0, buff.Length);

                                while (contentLen != 0)
                                {
                                    strm.Write(buff, 0, buff.Length);
                                    contentLen = fs.Read(buff, 0, buff.Length);
                                }

                                objFTP = null;
                            }
                        }



                    }
                }
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }

        public void deletar(int codigo, VW_usuarios user)
        {
            try
            {
                using (TransactionScope scope = new TransactionScope())
                {


                    

                    documento doc = Db.documentos.FirstOrDefault(x => x.doc_codigo == codigo);
                    doc.usuario_documento = Db.usuario_documento.Where(x => x.doc_codigo == codigo).ToList();
                    Db.documentos.Remove(doc);
                    Db.SaveChanges();

                    FtpWebRequest objFTP = null;
                    objFTP = Generica.FTPDetail(codigo.ToString() + doc.doc_extensao);
                    objFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                    try
                    {
                        objFTP.GetResponse();
                    }
                    catch (Exception)
                    {


                    }
                    finally
                    {

                        objFTP = null;
                    }

                    log logs = new log();
                    logs.log_modulo = 3;
                    logs.log_tipo = 1021;
                    logs.log_descricao = "Documento código: " + codigo;
                    logs.log_usuario = user.usu_codigo;
                    logs.log_data = DateTime.Now;
                    logs.log_horario = DateTime.Now.ToString("T");

                    Dbseg.log.Add(logs);
                    Dbseg.SaveChanges();

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public documento carrega_busca(long codigo)
        {
            try
            {
                documento doc = Db.documentos.FirstOrDefault(x => x.doc_codigo == codigo);

                return doc;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public origem_documentos busca_origem(int ori)

        {
            return Db.origem_documentos.FirstOrDefault(x => x.ori_codigo == ori);

        }

        public tipos_documentos busca_tipo(int tip_codigo)

        {
            return Db.tipos_documentos.FirstOrDefault(x => x.tip_codigo == tip_codigo);

        }

        public IEnumerable<VW_documentos_email> documentos_email(Int64 codigo)
        {
            try
            {
                return Db.VW_documentos_email.Where(x => x.doc_codigo == codigo).OrderBy(x => x.usu_email).ToList();
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        public tipos_origem_documentos busca_tipo_origens(int tip_codigo)

        {
            return Db.tipos_origem_documentos.FirstOrDefault(x => x.tip_codigo == tip_codigo);

        }

  
        public IEnumerable<VW_documentos_email> liberar_revogar(documento documento, VW_usuarios user)
        {
            try
            {

                var usuarios_doc_atual = Db.usuario_documento.Where(x => x.doc_codigo == documento.doc_codigo).Select(x => x.usu_codigo).ToList();

                using (TransactionScope scope = new TransactionScope())
                {

                    
                   
                    Db.usuario_documento.RemoveRange(Db.usuario_documento.Where(x => x.doc_codigo == documento.doc_codigo));
                    string[] vetor = documento.jsusuarios.Split(',');

                    foreach (string u in vetor)
                    {
                        if (u != "0")
                        {
                            usuario_documento usu = new usuario_documento();
                            usu.usu_codigo = int.Parse(u);
                            usu.doc_codigo = documento.doc_codigo;
                            documento.usuario_documento.Add(usu);
                        }
                    }


                    Db.usuario_documento.AddRange(documento.usuario_documento);
                    Db.SaveChanges();



                    log logs = new log();
                    logs.log_modulo = 3;
                    logs.log_tipo = 2221;
                    logs.log_descricao = "Documento código: " + documento.doc_codigo;
                    logs.log_usuario = user.usu_codigo;
                    logs.log_data = DateTime.Now;
                    logs.log_horario = DateTime.Now.ToString("T");

                    Dbseg.log.Add(logs);
                    Dbseg.SaveChanges();

                    scope.Complete();

                }
                var lista_envio_email = documento.usuario_documento.Select(x => x.usu_codigo).Except(usuarios_doc_atual);
                IEnumerable<VW_documentos_email> documentos_email = Db.VW_documentos_email.Where(x => x.doc_codigo == documento.doc_codigo).ToList();
                documentos_email = (from u in documentos_email where lista_envio_email.Contains(u.usu_codigo) select u).ToList();
                return documentos_email;

               
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public void copiar_perfil(int user_ori, int user_dest,VW_usuarios user)
        {
            try
            {

                

                using (TransactionScope scope = new TransactionScope())
                {



                    Db.usuario_documento.RemoveRange(Db.usuario_documento.Where(x => x.usu_codigo == user_dest));
                    Db.SaveChanges();

                    if (user_ori != -1)
                    {

                        List<usuario_documento> lista = new List<usuario_documento>();


                        foreach (usuario_documento u in Db.usuario_documento.Where(x => x.usu_codigo == user_ori))
                        {


                            usuario_documento usu = new usuario_documento();

                            usu.usu_codigo = user_dest;
                            usu.doc_codigo = u.doc_codigo;
                            lista.Add(usu);

                        }


                        Db.usuario_documento.AddRange(lista);
                        Db.SaveChanges();
                    }


                    log logs = new log();
                    logs.log_modulo = 3;
                    logs.log_tipo = 2222;
                    logs.log_descricao = "Usuário origem: " + user_ori + ", usuário destino: " + user_dest;
                    logs.log_usuario = user.usu_codigo;
                    logs.log_data = DateTime.Now;
                    logs.log_horario = DateTime.Now.ToString("T");

                    Dbseg.log.Add(logs);
                    Dbseg.SaveChanges();

                    scope.Complete();

                }
            


            }
            catch (Exception ex)
            {

                throw ex;
            }
        }



    }
}